@()(implicit session: Session)
@config.main("Primer designer") {

    <style>
            .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
                padding-left: 0;
                padding-right: 0;
            }


            #fasta {
                display: none;
            }

            p {
                font-size: 16px;
            }

            .length {
                color: #3498db;
                width: 60px;
            }

            .blue {
                color: #3498db;
            }

            .orange {
                color: #f39c12;
            }

            td {
                font-size: 16px;
            }

            .table > thead > tr > th {
                border-bottom: none;
            }

            .table > tbody > tr > td {
                border-top: none;
            }

            .tableHead {
                background-color: #3498db;
                color: white;
                font-size: 16px;
            }

            .tableText {
                background-color: #F39C12;
                color: white;
            }

            .tableText:hover {
                background-color: #e08e0b;
            }

            .tableBorder {
                background-color: #F9F9F9;
            }

            .tableBorder:hover {
                background-color: #ECF0F1;
            }

            .tableNoBorder:hover {
                background-color: #ECF0F1;
            }


            .has-feedback .form-control {
                padding-right: 0;
            }

    </style>

    <div class="body-box">
        <div class="page-box">

            @config.subTitle("Primer designer",detail = "Primer3 is a widely used program for designing PCR primers (PCR = \"Polymerase Chain Reaction\"). PCR is an essential and ubiquitous tool in genetics and molecular biology. Primer3 can also design hybridization probes and sequencing primers. ")

            <div class="main-body">


                <form class="registration-form col-sm-12 my-form" id="form">

                    <div class="row">

                        @components.radio("Type of query", "method", "range", Seq(("range", "Range"), ("seq", "Seq")), "ChangeMethod()", labelBox = "3")

                        <div id="range" style="width: 100%;
                            display: flex;
                            flex-wrap: wrap;">
                            @components.species("3","6",onchange = "getChr()")

                            @components.chr("3", "6")
                            @components.text("Start position", "start", "", "6", "6", "6")
                            @components.text("End position", "end", "", "6", "3", "6")
                        </div>

                        <div id="fasta" style="width: 100%;">
                        @components.textarea("Enter FASTA sequences", "queryText", "queryText", "getExample()")

                        </div>
                        <h5 style="margin-left: 40px">Parameter Selection:</h5>

                        @components.text("Sequence target", "SEQUENCE_TARGET", "50,350", "12", "3", "6",detail = "If one or more targets is specified then a legal primer pair must flank at least one of them. A target might be a simple sequence repeat site (for example a CA repeat) or a single-base-pair polymorphism, or an exon for resequencing. The value should be a space-separated list of<br/><br/><i>(start),(length)</i><br/><br/>pairs where (start) is the index of the first base of a target, and (length) is its length.<br/>See also PRIMER_INSIDE_PENALTY, PRIMER_OUTSIDE_PENALTY. Has a different meaning when PRIMER_TASK=pick_sequencing_primers. See PRIMER_TASK for more information. ")
                        @components.text("Product Size Ranges", "PRIMER_PRODUCT_SIZE_RANGE", "100-300,300-600,600-1000", "12", "3", "6",detail="The associated values specify the lengths of the product that the user wants the primers to create, and is a space separated list of elements of the form</br></br>(x)-(y)</br></br>where an (x)-(y) pair is a legal range of lengths for the product. For example, if one wants PCR products to be between 100 to 150 bases (inclusive) then one would set this parameter to 100-150. If one desires PCR products in either the range from 100 to 150 bases or in the range from 200 to 250 bases then one would set this parameter to 100-150 200-250.</br></br>Primer3 favors product-size ranges to the left side of the parameter string. Primer3 will return legal primers pairs in the first range regardless the value of the objective function for pairs in subsequent ranges. Only if there are an insufficient number of primers in the first range will Primer3 return primers in a subsequent range.</br></br>For those with primarily a computational background, the PCR product size is the size (in base pairs) of the DNA fragment that would be produced by the PCR reaction on the given sequence template. This would, of course, include the primers themselves.")

                        @components.text("Optimal primer size", "PRIMER_OPT_SIZE", "20", "4", "9", "3",detail="Optimum length (in bases) of a primer. Primer3 will attempt to pick primers close to this length.")
                        @components.text("Max primer size", "PRIMER_MAX_SIZE", "25", "3", "8", "4",detail="Maximum acceptable length (in bases) of a primer. Currently this parameter cannot be larger than 35. This limit is governed by maximum oligo size for which Primer3's melting-temperature is valid.")
                        @components.text("Min primer size", "PRIMER_MIN_SIZE", "18", "3", "8", "4",detail="Minimum acceptable length of a primer. Must be greater than 0 and less than or equal to PRIMER_MAX_SIZE.")

                        @components.text("Optimal primer TM", "PRIMER_OPT_TM", "59.0", "4", "9", "3",detail="Optimum melting temperature (Celsius) for a primer. Primer3 will try to pick primers with melting temperatures are close to this temperature. The oligo melting temperature formula used can be specified by user. Please see PRIMER_TM_FORMULA for more information.")
                        @components.text("Max primer TM", "PRIMER_MAX_TM", "62.0", "3", "8", "4",detail="Maximum acceptable melting temperature (Celsius) for a primer oligo.")
                        @components.text("Min primer TM", "PRIMER_MIN_TM", "57.0", "3", "8", "4",detail="Minimum acceptable melting temperature (Celsius) for a primer oligo.")

                        @components.text("Optimal GC percent", "PRIMER_OPT_GC_PERCENT", "50.0", "4", "9", "3",detail="Optimum GC percent. This parameter influences primer selection only if PRIMER_WT_GC_PERCENT_GT or PRIMER_WT_GC_PERCENT_LT are non-0.")
                        @components.text("Max GC percent", "PRIMER_MAX_GC", "80.0", "3", "8", "4",detail="Maximum allowable percentage of Gs and Cs in any primer generated by Primer.")
                        @components.text("Min GC percent", "PRIMER_MIN_GC", "20.0", "3", "8", "4",detail="Minimum allowable percentage of Gs and Cs in any primer.")

                        @components.text("Max #N's accepted", "PRIMER_MAX_NS_ACCEPTED", "0", "4", "9", "3",detail="Maximum number of unknown bases (N) allowable in any primer.")
                        @components.text("Max Poly-X", "PRIMER_MAX_POLY_X", "10", "3", "8", "4",detail="The maximum allowable length of a mononucleotide repeat, for example AAAAAA.")
                        @components.text("Max Internal Poly-X", "PRIMER_INTERNAL_MAX_POLY_X", "15", "3", "8", "4",detail="Equivalent parameter of PRIMER_MAX_POLY_X for the internal oligo.")

                        @components.text("Max Self Complementarity", "PRIMER_MAX_SELF_ANY", "45.0", "4", "9", "3",detail="PRIMER_MAX_SELF_ANY describes the tendency of a primer to bind to itself (interfering with target sequence binding). It will score ANY binding occurring within the entire primer sequence.<br/>It is the maximum allowable local alignment score when testing a single primer for (local) self-complementarity. Local self-complementarity is taken to predict the tendency of primers to anneal to each other without necessarily causing self-priming in the PCR. The scoring system gives 1.00 for complementary bases, -0.25 for a match of any base (or N) with an N, -1.00 for a mismatch, and -2.00 for a gap. Only single-base-pair gaps are allowed. ")
                        @components.text("Max 3' Self Complementarity", "PRIMER_MAX_SELF_END", "35.0", "6", "8", "2",detail="PRIMER_MAX_SELF_END tries to bind the 3'-END to a identical primer and scores the best binding it can find. This is critical for primer quality because it allows primers use itself as a target and amplify a short piece (forming a primer-dimer). These primers are then unable to bind and amplify the target sequence.<br/>PRIMER_MAX_SELF_END is the maximum allowable 3'-anchored global alignment score when testing a single primer for self-complementarity. The 3'-anchored global alignment score is taken to predict the likelihood of PCR-priming primer-dimers.")

                        @components.text("Max Pair Complementarity", "PRIMER_PAIR_MAX_COMPL_ANY", "45.0", "4", "9", "3",detail="PRIMER_PAIR_MAX_COMPL_ANY describes the tendency of the left primer to bind to the right primer. It is the maximum allowable local alignment score when testing for complementarity between left and right primers. It is similar to PRIMER_MAX_SELF_ANY.")
                        @components.text("Max 3' Pair Complementarity", "PRIMER_PAIR_MAX_COMPL_END", "35.0", "6", "8", "2",detail="PRIMER_PAIR_MAX_COMPL_END tries to bind the 3'-END of the left primer to the right primer and scores the best binding it can find. It is similar to PRIMER_MAX_SELF_END.")
                    </div>


                    <div class="col-md-12 form-group">
                        <label class="col-sm-3"></label>
                        <button type="button" class="btn my-btn" style="width: 200px" onclick="Search()">
                            Search</button>

                    </div>

                </form>


                <div id="result" style="display: none;">

                </div>

            </div>
        </div>
    </div>

    <script>

            $(function () {
                ChangeMethod()
                formValidation()

                $("#species").select2()
                getChr()
            })

            function getChr() {
                let species =  $("#species").val()
                $.post("/COADB/search/getChr?species=" + species, (data) => {
                    $("#chr").empty().select2({data:data})
                })
            }


            function Search() {
                let form = $("#form");
                let fv = form.data("formValidation");
                fv.validate();
                if (fv.isValid()) {
                    let index = MyTable.prototype.runningIcon();
                    $.ajax({
                        url: "@routes.ToolsController.toolsRun("primer")",
                        type: "post",
                        data: form.serialize(),
                        success: function (data) {
                            layer.close(index);

                            if (data.valid === "false") {
                                swal("Error", data.message, "error");
                                $("#result").hide()
                            } else {
                                let $result = $("#result")
                                $result.html(data.result);
                                $result.show();
                                let target_top = $result.offset().top ;
                                $("html,body").animate({scrollTop: target_top}, 800);
                            }
                        }
                    });
                }
            }

            function ChangeMethod() {
                let value = $("input[name=method]:checked").val()
                if (value === "range") {
                    $("#range").show()
                    $("#fasta").hide()
                } else {
                    $("#fasta").show()
                    $("#range").hide()
                }
            }

            function getExample() {
                let seq = "AACCCTAAACCTAAACCCTAAACCCTAAACCCTAAACCCTAACCCTAAACCCTAAACGCTAAACCCTAAACCCTAAACCCTAAACCCTAAACCCTAAACCCTAAACCCTAAACCCTAACCCTAAACCCTAAACCCTAACCCTAAACCCTAAACCCTAAACCCTAACCCTAAACCCTAAACCCTAAACCCTAAACCCTAAACCCTAAACAGCTGACAGTACGATAGATCCACGCGAGAGGAACCGGAGAGACAACGGGATCCAGGCGCCAGCGACGGATCCGGGCGAGAGGGGAGTGGAGATCATGGATCCGTGCGGGAGGGGAAGAAGTCGCCGAATCCGACCCTCCCATCGCCATCGACAGTAGGTCTGCGCGAGAGGGGCACCGGCGCTGGCTCTGAGCGAGATGCAACGCCGGCCGGCTTGGAGAGTAACTCAAGAGAGACAGAATGGAAGATAGAGAACAAGAGAGTGAGAGGATAAGGATATAGACCAGACCACACAATTTTCTCTTCTTTTTAACTTTGTATTAAGATCTTTTATGGAACATCTTTTATTGTTGATATCAAAATAACTGAAACTTATACTTTAATATTTTTTGAGACAAAAAGTAACAATCGTAAAAAAAAGTTCCACGAGAGTTACCCCACCACCCATGTCTCGAGCCGACCAGATCTGCCGCCCACGACCCGAGTCATCGTTGGATCCACCACCCACAACCCGCGACCGAGCTACGCCTCCTGTGGATTGATGCCACTGCCCTGAGCTTCACTGCCGGTACTGTCGCTCGCGACCCGAGCTCCGCCGCTGGTACCGTCGCCCACAACTCAAGCTGTGTTGCCACTAGAGAAAAAGGAGGCGAGAGCGAGGGCAAAACGAGGCAAGGCGTGGCGTGACATGGTGTGACTGGTTGGTCAATTAGCCGACAATGGATCCACCGCCCATGAACCGAGCCACCGTTGGATCCGCCACCCGCAGATTCGGCTGTCCCCTCTCCCTCA"
                $("#queryText").val(seq)
            }

            function formValidation() {
                $('#form').formValidation({
                    framework: 'bootstrap',
                    icon: {
                        valid: 'glyphicon glyphicon-ok',
                        invalid: 'glyphicon glyphicon-remove',
                        validating: 'glyphicon glyphicon-refresh'
                    },
                    fields: {
                        start: {
                            validators: {
                                notEmpty: {
                                    message: 'Start position is required！'
                                },
                                numeric: {
                                    message: 'Start position must be number！'
                                },
                                greaterThan: {
                                    value: 0,
                                    message: "Start position must greater than or equal to 0！"
                                },
                                callback: {
                                    message: 'Start position must less than end position!',
                                    callback: function (value, validator) {
                                        var end = $("#end").val();
                                        if (end === "" || value === "") {
                                            return true;
                                        } else {
                                            validator.updateStatus("end", validator.STATUS_VALID, 'callback');
                                            return parseInt(value) < parseInt(end);
                                        }
                                    }
                                }
                            }
                        },
                        end: {
                            validators: {
                                notEmpty: {
                                    message: 'End positionis required！'
                                },
                                numeric: {
                                    message: 'End position must be number！'
                                },
                                greaterThan: {
                                    value: 0,
                                    message: "End position must greater than or equal to 0！"
                                },
                                callback: {
                                    message: 'End position must greater than start position!',
                                    callback: function (value, validator) {
                                        var start = $("#start").val();
                                        if (start === "" || value === "") {
                                            return true;
                                        } else {
                                            validator.updateStatus("start", validator.STATUS_VALID, 'callback');
                                            return parseInt(start) < parseInt(value);
                                        }
                                    }
                                }
                            }
                        },
                        queryText:{
                            validators: {
                                notEmpty: {
                                    message: 'FASTA sequences is required！'
                                }
                            }
                        },
                        SEQUENCE_TARGET: {
                            validators: {
                                notEmpty: {
                                    message: 'Sequence target is required！'
                                }
                            }
                        },
                        PRIMER_OPT_SIZE: {
                            validators: {
                                notEmpty: {
                                    message: 'Optimal primer size is required！'
                                },
                                integer: {
                                    message: 'Optimal primer size must be integer！'
                                }
                            }
                        },
                        PRIMER_MAX_SIZE: {
                            validators: {
                                notEmpty: {
                                    message: '>Max primer size is required！'
                                },
                                integer: {
                                    message: '>Max primer size must be integer！'
                                }
                            }
                        },
                        PRIMER_MIN_SIZE: {
                            validators: {
                                notEmpty: {
                                    message: 'Min primer size is required！'
                                },
                                integer: {
                                    message: 'Min primer size must be integer！'
                                }
                            }
                        },
                        PRIMER_OPT_TM: {
                            validators: {
                                notEmpty: {
                                    message: 'Optimal primer TM is required！'
                                },
                                numeric: {
                                    message: 'Optimal primer TM must be number！'
                                }
                            }
                        },
                        PRIMER_MAX_TM: {
                            validators: {
                                notEmpty: {
                                    message: 'Max primer TM is required！'
                                },
                                numeric: {
                                    message: 'Max primer TM must be number！'
                                }
                            }
                        },
                        PRIMER_MIN_TM: {
                            validators: {
                                notEmpty: {
                                    message: 'Min primer TM is required！'
                                },
                                numeric: {
                                    message: 'Min primer TM must be number！'
                                }
                            }
                        },
                        PRIMER_OPT_GC_PERCENT: {
                            validators: {
                                notEmpty: {
                                    message: 'Optimal GC percent is required！'
                                },
                                numeric: {
                                    message: 'Optimal GC percent must be number！'
                                }
                            }
                        },
                        PRIMER_MAX_GC: {
                            validators: {
                                notEmpty: {
                                    message: 'Max GC percent is required！'
                                },
                                numeric: {
                                    message: 'Max GC percent must be number！'
                                }
                            }
                        },
                        PRIMER_MIN_GC: {
                            validators: {
                                notEmpty: {
                                    message: 'Min GC percent is required！'
                                },
                                numeric: {
                                    message: 'Min GC percent must be number！'
                                }
                            }
                        },
                        PRIMER_MAX_NS_ACCEPTED: {
                            validators: {
                                notEmpty: {
                                    message: "Max #N's accepted is required！"
                                },
                                integer: {
                                    message: "Max #N's accepted must be integer！"
                                }
                            }
                        },
                        PRIMER_MAX_POLY_X: {
                            validators: {
                                notEmpty: {
                                    message: 'Max Poly-X is required！'
                                },
                                integer: {
                                    message: 'Max Poly-X must be integer！'
                                }
                            }
                        },
                        PRIMER_INTERNAL_MAX_POLY_X: {
                            validators: {
                                notEmpty: {
                                    message: 'Max Internal Poly-X is required！'
                                },
                                integer: {
                                    message: 'Max Internal Poly-X must be integer！'
                                }
                            }
                        },
                        PRIMER_MAX_SELF_ANY: {
                            validators: {
                                notEmpty: {
                                    message: 'Max Self Complementarity is required！'
                                },
                                numeric: {
                                    message: 'Max Self Complementarity must be number！'
                                }
                            }
                        },
                        PRIMER_MAX_SELF_END: {
                            validators: {
                                notEmpty: {
                                    message: "Max 3' Self Complementarity is required！"
                                },
                                numeric: {
                                    message: "Max 3' Self Complementarity must be number！"
                                }
                            }
                        },
                        PRIMER_PAIR_MAX_COMPL_ANY: {
                            validators: {
                                notEmpty: {
                                    message: 'Max Pair Complementarity is required！'
                                },
                                numeric: {
                                    message: 'Max Pair Complementarity must be number！'
                                }
                            }
                        },
                        PRIMER_PAIR_MAX_COMPL_END: {
                            validators: {
                                notEmpty: {
                                    message: "Max 3' Pair Complementarity is required！"
                                },
                                numeric: {
                                    message: "Max 3' Pair Complementarity must be number！"
                                }
                            }
                        }
                    }
                });
            }


    </script>
}